package cn.hg.solon.youcan.system.provider;

import static cn.hg.solon.youcan.system.entity.table.SysUserOnlineTableDef.SYS_USER_ONLINE;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.convert.Convert;
import org.dromara.hutool.core.text.CharSequenceUtil;
import org.dromara.hutool.core.text.StrValidator;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.db.PageResult;
import org.noear.solon.annotation.Component;
import org.noear.solon.data.annotation.Tran;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryOrderBy;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.util.UpdateEntity;
import com.mybatisflex.solon.service.impl.ServiceImpl;

import cn.hg.solon.youcan.common.enums.OnlineStatus;
import cn.hg.solon.youcan.system.entity.SysUserOnline;
import cn.hg.solon.youcan.system.entity.UserOnline;
import cn.hg.solon.youcan.system.mapper.SysUserOnlineMapper;
import cn.hg.solon.youcan.system.service.UserOnlineService;

/**
 * @author 胡高
 */
@Component
public class SysUserOnlineProvider extends ServiceImpl<SysUserOnlineMapper, SysUserOnline>
implements UserOnlineService {

    @Override
    public UserOnline get(String token) {
        return this.getMapper().selectOneById(token);
    }

    @Tran
    @Override
    public boolean insert(UserOnline bean) {
        SysUserOnline cloneBean = BeanUtil.copyProperties(bean, SysUserOnline.class);

        return this.getMapper().insert(cloneBean) > 0;
    }

    @Tran
    @Override
    public boolean offline(String token) {
        SysUserOnline entity = UpdateEntity.of(SysUserOnline.class);
        entity.setId(token);
        entity.setStatus(OnlineStatus.OFF.name());
        return this.getMapper().update(entity) > 0;
    }

    @Override
    public List<? extends UserOnline> onlineList() {
        return this.getMapper().selectListByCondition(SYS_USER_ONLINE.STATUS.eq(OnlineStatus.ON.name()));
    }

    @Override
    public PageResult<? extends UserOnline> pageBy(int pageNumber, int pageSize, Map<String, Object> paraMap) {
        String word = (String)paraMap.get("word");
        String status = (String)paraMap.get("status");
        Date startDate = (Date)paraMap.get("startDate");
        Date endDate = (Date)paraMap.get("endDate");
        String sortField = (String)paraMap.get("sortField");
        String sortType = (String)paraMap.get("sortType");

        // FROM sys_user_online AS t
        QueryWrapper query = QueryWrapper.create()
            // WHERE t.`status` = ${status} AND t.`start_datetime` > ${startDate} AND t.`start_datetime` < ${endDate}
            .where(SYS_USER_ONLINE.STATUS.eq(status).when(StrValidator.isNotBlank(status))
                .and(SYS_USER_ONLINE.START_DATETIME.ge(startDate).when(ObjUtil.isNotNull(startDate)))
                .and(SYS_USER_ONLINE.START_DATETIME.le(endDate).when(ObjUtil.isNotNull(endDate)))
                // AND (t.`nickname` LIKE '%${word}%' OR t.`dept_name` LIKE '%${word}%' OR t.`ip` LIKE '%${word}%'
                //      OR t.`location` LIKE '%${word}%' OR t.`browser` LIKE '%${word}%' OR t.`os` LIKE '%${word}%'
                //      OR t.`id` LIKE '%${word}%')
                .and(SYS_USER_ONLINE.BROWSER.like(word).when(StrValidator.isNotBlank(word))
                    .or(SYS_USER_ONLINE.DEPT_NAME.like(word).when(StrValidator.isNotBlank(word)))
                    .or(SYS_USER_ONLINE.LOCATION.like(word).when(StrValidator.isNotBlank(word)))
                    .or(SYS_USER_ONLINE.NICKNAME.like(word).when(StrValidator.isNotBlank(word)))
                    .or(SYS_USER_ONLINE.OS.like(word).when(StrValidator.isNotBlank(word)))
                    .or(SYS_USER_ONLINE.ID.like(word).when(StrValidator.isNotBlank(word)))
                    )
                );

        if (StrValidator.isNotBlank(sortField) && StrValidator.isNotBlank(sortType)) {
            query.orderBy(new QueryOrderBy(new QueryColumn(CharSequenceUtil.toUnderlineCase(sortField)), sortType));
        }

        Page<SysUserOnline> pageList = this.getMapper().paginate(Page.of(pageNumber, pageSize), query);

        PageResult<UserOnline> result = new PageResult<>();
        result.addAll(pageList.getRecords());
        result.setTotal(Convert.toInt(pageList.getTotalRow()));

        return result;
    }

    @Tran
    @Override
    public void syncActivityTime(String token, Date datetime) {
        SysUserOnline entity = UpdateEntity.of(SysUserOnline.class, token);
        entity.setActivityDatetime(datetime);

        this.getMapper().update(entity);
    }

    @Tran
    @Override
    public boolean update(UserOnline bean) {
        SysUserOnline cloneBean = BeanUtil.copyProperties(bean, SysUserOnline.class);

        return this.getMapper().update(cloneBean) > 0;
    }

}
